home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xquinto / xquinto_xview.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  13.6 KB  |  539 lines

  1. #include <stdio.h>
  2. #include <xview/xview.h>
  3. #include <xview/canvas.h>
  4. #include <xview/panel.h>
  5. #include <xview/xv_xrect.h>
  6. #include <xview/notice.h>
  7. #include <X11/Xlib.h>
  8. #include <strings.h>
  9. #include "copyright.h"
  10.  
  11. #include "white.xbm"
  12. #include "gray.xbm"
  13.  
  14. #define HEIGHT  20  /* of game */
  15. #define WIDTH   20
  16. #define SWIDTH  40  /* of cells */
  17. #define SHEIGHT 40 
  18. #define BWIDTH  14  /* of border */
  19. #define BHEIGHT 14
  20.  
  21. void keyboard();
  22. void draw_screen();
  23. void DrawCell();
  24. void newscreen();
  25. unsigned long getcolor();
  26. int quit();
  27.  
  28. int myarr[HEIGHT][WIDTH];
  29. int height;
  30. int width;
  31. int showmove;
  32. int clearscreen = 0;
  33. int update_x, update_y;
  34. char colorname[4][64] =
  35. {
  36.     "notused","red","blue", "yellow"
  37. };
  38. Pixmap patpix[4];
  39. Pixmap showpix[2];
  40. Colormap cmap;
  41. Display *display;
  42. Window xwin;
  43. Xv_Window xv_win;
  44. GC gc;
  45. int screen;
  46. unsigned long foreground, background;
  47. int mono = 0;
  48.  
  49.  
  50. main(argc,argv)
  51.     int argc;
  52.     char *argv[];
  53. {
  54.     int i = 1;
  55.     Frame frame;
  56.     Canvas canvas;
  57.     Panel panel;
  58.  
  59.     void canvas_proc();
  60.     void event_proc();
  61.     void clear_proc();
  62.     void width_proc();
  63.     void height_proc();
  64.     void show_proc();
  65.     Xv_opaque help_proc();
  66.     Xv_opaque quit_proc();
  67.     void startup();
  68.     
  69.     xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
  70.  
  71.     height = 5;
  72.     width = 5;
  73.     while (i < argc && argv[i][0] == '-') {
  74.         if (strcmp(argv[i], "-height") == 0) {
  75.             height = atoi(argv[i+1]);
  76.             i++;
  77.         }
  78.         else if (strcmp(argv[i], "-width") == 0) {
  79.             width = atoi(argv[i+1]);
  80.             i++;
  81.         }
  82.         else if (strcmp(argv[i], "-color1") == 0) {
  83.             sprintf(colorname[1], argv[i+1]);
  84.             i++;
  85.         }
  86.         else if (strcmp(argv[i], "-color2") == 0) {
  87.             sprintf(colorname[2], argv[i+1]);
  88.             i++;
  89.         }
  90.         else if (strcmp(argv[i], "-color3") == 0) {
  91.             sprintf(colorname[3], argv[i+1]);
  92.             i++;
  93.         }
  94.         else if (strcmp(argv[i], "-mono") == 0) {
  95.             mono = 1;
  96.         }
  97.         else if (strcmp(argv[i], "-square") == 0) {
  98.             width = atoi(argv[i+1]);
  99.             height = width;
  100.             i++;
  101.         }
  102.         i++;
  103.     }
  104.     width = (width > WIDTH) ? WIDTH : width;
  105.     height = (height > HEIGHT) ? HEIGHT : height;
  106.  
  107.     
  108.     frame = (Frame)xv_create(NULL, FRAME,
  109.                              FRAME_LABEL, argv[0],
  110.                              XV_WIDTH, 140 + width*SWIDTH, 
  111.                              XV_HEIGHT, height*SHEIGHT + 2*BHEIGHT + 57, 
  112.                              NULL);
  113.  
  114.     panel = xv_create(frame, PANEL, 
  115.                       XV_HEIGHT, 55,
  116.                       NULL);
  117.  
  118.     (void)xv_create(panel, PANEL_BUTTON,
  119.                     PANEL_LABEL_STRING, "Quit",
  120.                     PANEL_NOTIFY_PROC, quit_proc,
  121.                     NULL);
  122.  
  123.     (void)xv_create(panel, PANEL_BUTTON,
  124.                     PANEL_LABEL_STRING, "Clear",
  125.                     PANEL_NOTIFY_PROC, clear_proc,
  126.                     NULL);
  127.  
  128.     (void)xv_create(panel, PANEL_BUTTON,
  129.                     PANEL_LABEL_STRING, "Show Moves",
  130.                     PANEL_NOTIFY_PROC, show_proc,
  131.                     NULL);
  132.  
  133.     (void)xv_create(panel, PANEL_BUTTON,
  134.                     PANEL_LABEL_STRING, "Help",
  135.                     PANEL_NOTIFY_PROC, help_proc,
  136.                     NULL);
  137.                     
  138.     (void)xv_create(panel, PANEL_NUMERIC_TEXT,
  139.                     PANEL_LABEL_STRING, "Width",
  140.                     PANEL_VALUE, width,
  141.                     PANEL_NEXT_ROW, -1,
  142.                     PANEL_MIN_VALUE, 1,
  143.                     PANEL_MAX_VALUE, 20,
  144.                     PANEL_VALUE_DISPLAY_LENGTH, 1,
  145.                     PANEL_NOTIFY_PROC, width_proc,
  146.                     NULL);
  147.     
  148.     (void)xv_create(panel, PANEL_NUMERIC_TEXT,
  149.                     PANEL_LABEL_STRING, "Height",
  150.                     PANEL_VALUE, height,
  151.                     PANEL_MIN_VALUE, 1,
  152.                     PANEL_MAX_VALUE, 20,
  153.                     PANEL_VALUE_DISPLAY_LENGTH, 1,
  154.                     PANEL_NOTIFY_PROC, height_proc,
  155.                     NULL);
  156.  
  157.     canvas = xv_create(frame, CANVAS,
  158.                        CANVAS_REPAINT_PROC, canvas_proc,
  159.                        CANVAS_X_PAINT_WINDOW, TRUE,
  160.                        CANVAS_AUTO_EXPAND, TRUE,
  161.                        CANVAS_AUTO_SHRINK, TRUE,
  162.                        NULL);
  163.     window_fit(frame);
  164.  
  165.     startup(frame, canvas);
  166.     xv_set(canvas_paint_window(canvas),
  167.            WIN_EVENT_PROC, event_proc,
  168.            WIN_CONSUME_EVENTS,
  169.              KBD_DONE, KBD_USE, LOC_DRAG, LOC_MOVE, LOC_WINENTER,
  170.              LOC_WINEXIT, WIN_ASCII_EVENTS, WIN_MOUSE_BUTTONS,
  171.              NULL,
  172.            NULL);
  173.     update_x = -1;
  174.     xv_main_loop(frame);
  175. }
  176.  
  177. InArray(x,y)
  178. {
  179.     return ((x >= 0 && x < width) && (y >= 0 && y < height)) ? 1 : 0;
  180. }
  181.  
  182. mymarkcell(x, y)
  183.     int x;
  184.     int y;
  185.  
  186. {
  187.     if (InArray(x,y)) {
  188.         myarr[x][y] = 3 - myarr[x][y];
  189.     }
  190.     if (InArray(x-1,y)) {
  191.         myarr[x-1][y] = (2 + myarr[x-1][y])%4;
  192.     }
  193.     if (InArray(x+1,y)) {
  194.         myarr[x+1][y] = (2 + myarr[x+1][y])%4;
  195.     }
  196.     if (InArray(x,y+1)) {
  197.         myarr[x][y+1] = (2 + myarr[x][y+1])%4;
  198.     }
  199.     if (InArray(x,y-1)) {
  200.         myarr[x][y-1] = (2 + myarr[x][y-1])%4;
  201.     }
  202. }
  203.  
  204. void clear_proc(item, event)
  205.     Panel_item item;
  206.     Event *event;
  207. {
  208.     clearscreen = 1;
  209.     newscreen();
  210.     canvas_proc((Canvas)NULL, xv_win, (Display*)xv_get(xv_win, XV_DISPLAY),
  211.                 xwin, (Xv_xrectlist *)NULL);
  212.  
  213. }
  214.  
  215. void width_proc(item, event)
  216.     Panel_item item;
  217.     Event *event;
  218. {
  219.     width = xv_get(item, PANEL_VALUE);
  220.     clearscreen = 1;
  221.     newscreen();
  222.     canvas_proc((Canvas)NULL, xv_win, (Display*)xv_get(xv_win, XV_DISPLAY),
  223.                 xwin, (Xv_xrectlist *)NULL);
  224.  
  225. }
  226.  
  227. void height_proc(item, event)
  228.     Panel_item item;
  229.     Event *event;
  230. {
  231.     height = xv_get(item, PANEL_VALUE);
  232.     clearscreen = 1;
  233.     newscreen();
  234.     canvas_proc((Canvas)NULL, xv_win, (Display*)xv_get(xv_win, XV_DISPLAY),
  235.                 xwin, (Xv_xrectlist *)NULL);
  236.  
  237. }
  238.  
  239. void show_proc(item, event)
  240.     Panel_item item;
  241.     Event *event;
  242. {
  243.     showmove = 1 - showmove;
  244.     clearscreen = 1;
  245.     if(showmove) { /* show the '.' on clicked squares */
  246.         patpix[1] = showpix[0];
  247.         patpix[3] = showpix[1];
  248.     }
  249.     else {
  250.         patpix[1] = patpix[0];
  251.         patpix[3] = patpix[2];
  252.     }
  253.     canvas_proc((Canvas)NULL, xv_win, (Display*)xv_get(xv_win, XV_DISPLAY),
  254.                 xwin, (Xv_xrectlist *)NULL);
  255.  
  256. }
  257.  
  258. Xv_opaque help_proc(item, event)
  259.     Panel_item item;
  260.     Event *event;
  261. {
  262.     int result;
  263.     Panel panel = (Panel)xv_get(item, PANEL_PARENT_PANEL);
  264.     
  265.     result = notice_prompt(panel, NULL,
  266.                NOTICE_MESSAGE_STRINGS,
  267.                  "Xquinto is a puzzle on a rectangular board. Clicking on",
  268.                  "any square reverses its color, and that of its neighbors",
  269.                  "that share an edge (not the diagonal ones). The object,",
  270.                  "starting from a red board, is to color each square blue.",
  271.                  "   ",
  272.                  "The 5 by 5 puzzle can be solved!",
  273.                  "   ",
  274.                  "Dev Joneja, dj7@cunixf.cc.columbia.edu",
  275.                  NULL,
  276.                NOTICE_BUTTON_YES, "OK",
  277.                NULL);
  278.     if (result == NOTICE_YES) return;
  279. }
  280.  
  281.  
  282. Xv_opaque quit_proc(item, event)
  283.     Panel_item item;
  284.     Event *event;
  285. {
  286.     int result;
  287.     Panel panel = (Panel)xv_get(item, PANEL_PARENT_PANEL);
  288.     
  289.     result = notice_prompt(panel, NULL,
  290.                NOTICE_MESSAGE_STRINGS,
  291.                  "What... already?", NULL,
  292.                NOTICE_BUTTON_YES, "jah",
  293.                NOTICE_BUTTON_NO, "no mon",
  294.                NULL);
  295.     if (result == NOTICE_YES) quit();
  296.     if (result == NOTICE_NO) return;
  297. }
  298.  
  299. void event_proc(window, event)
  300.     Xv_window window;
  301.     Event *event;
  302. {
  303.     static int x,y;
  304.  
  305.     if (event_is_ascii(event)) {
  306.         if (event_is_down(event)) 
  307.             keyboard(event_action(event));
  308.     }
  309.     else
  310.         switch (event_action(event)) {
  311.         case ACTION_SELECT:
  312.         case MS_LEFT:
  313.         case ACTION_ADJUST:
  314.         case MS_MIDDLE:
  315.         case ACTION_MENU:
  316.         case MS_RIGHT:
  317.             if (event_is_down(event)) {
  318.                 x = (event_x(event)-BWIDTH)/SWIDTH;
  319.                 y = (event_y(event)-BHEIGHT)/SHEIGHT;
  320.                 if (InArray(x,y)) {
  321.                     mymarkcell(x,y);
  322.                     update_x = x;
  323.                     update_y = y;
  324.                 }
  325.             }
  326.             else return;
  327.             break;
  328.         default:
  329.             return;
  330.         }
  331.     canvas_proc((Canvas)NULL, window, (Display*)xv_get(window, XV_DISPLAY),
  332.                 xv_get(window, XV_XID), (Xv_xrectlist *)NULL);
  333. }
  334.  
  335. void canvas_proc(canvas, pwin, dpy, x_win, xrects)
  336.     Canvas canvas;
  337.     Xv_Window pwin;
  338.     Display *dpy;
  339.     Window x_win;
  340.     Xv_xrectlist *xrects;
  341. {
  342.     if (clearscreen) {
  343.         XClearWindow(dpy, x_win);
  344.         clearscreen = 0;
  345.     }
  346.     draw_screen();
  347. }
  348.  
  349. void newscreen()
  350. {
  351.     int i,j,k;
  352.     int x,y;
  353.  
  354.     for(i=0; i < width; i++)
  355.         for(j=0; j < height; j++)
  356.             myarr[i][j] = 0;
  357. }
  358.  
  359.  
  360. int quit()
  361. {
  362.     exit(1);
  363. }
  364.  
  365.  
  366. void startup(frame, canvas)
  367.     Frame frame;
  368.     Canvas canvas;
  369. {
  370.     int i;
  371.     int depth;
  372.     char *pixstr = ".";
  373.     unsigned long patbg, patfg;
  374.     char fontname[80];
  375.     XFontStruct *xfontinfo;
  376.  
  377.     display = (Display *)xv_get(frame, XV_DISPLAY);
  378.     screen = DefaultScreen(display);
  379.     depth = DefaultDepth(display,screen);
  380.     if (depth < 2) mono = 1;
  381.     gc = DefaultGC(display, screen);
  382.     xv_win = canvas_paint_window(canvas);
  383.     xwin = xv_get(xv_win, XV_XID);
  384.  
  385.     /* default pixel values */
  386.     cmap = DefaultColormap(display, screen);
  387.  
  388.     background = WhitePixel(display, screen);
  389.     foreground = BlackPixel(display, screen);
  390.     XSetBackground(display, gc, background);
  391.     XSetForeground(display, gc, foreground);
  392.  
  393.     sprintf(fontname, "8x13bold");
  394.     if((xfontinfo = XLoadQueryFont(display,fontname)) == NULL)
  395.     {
  396.         fprintf(stderr,"Can't find font '%s'\n",fontname);
  397.         xfontinfo = XQueryFont(display,XGContextFromGC(gc));
  398.     }
  399.     XSetFont(display,gc,xfontinfo->fid); 
  400.  
  401.     if(!mono) patbg = getcolor(colorname[1] ,background); 
  402.     patpix[0] = XCreatePixmapFromBitmapData(display,xwin,
  403.                         gray_xbm_bits,SWIDTH,SHEIGHT,foreground,
  404.                         patbg, depth);
  405.     showpix[0] = XCreatePixmapFromBitmapData(display,xwin,
  406.                         gray_xbm_bits,SWIDTH,SHEIGHT,foreground,
  407.                         patbg, depth);
  408.     if(!mono) patbg = getcolor(colorname[2],background); 
  409.     patpix[2] = XCreatePixmapFromBitmapData(display,xwin,
  410.                         white_xbm_bits,SWIDTH,SHEIGHT,foreground,
  411.                         patbg, depth);
  412.     showpix[1] = XCreatePixmapFromBitmapData(display,xwin,
  413.                         white_xbm_bits,SWIDTH,SHEIGHT,foreground,
  414.                         patbg, depth);
  415.     /* put the '.' on the showpix */
  416.     patfg = getcolor(colorname[3],foreground);  
  417.     XSetForeground(display, gc, patfg);
  418.     XDrawString(display,showpix[0],gc,SWIDTH/2-3,SHEIGHT/2,pixstr,1);
  419.     XDrawString(display,showpix[1],gc,SWIDTH/2-3,SHEIGHT/2,pixstr,1);
  420.     XSetForeground(display, gc, foreground);
  421.  
  422.     if(showmove) { /* show the '.' on clicked squares */
  423.         patpix[1] = showpix[0];
  424.         patpix[3] = showpix[1];
  425.     }
  426.     else {
  427.         patpix[1] = patpix[0];
  428.         patpix[3] = patpix[2];
  429.     }
  430. }
  431.  
  432. unsigned long getcolor(s,monocolor)
  433.     char *s;
  434.     unsigned long monocolor;
  435. {
  436.     XColor exact_def;
  437.  
  438.     if(!mono) {
  439.         XParseColor(display, cmap, s, &exact_def);
  440.         XAllocColor(display, cmap, &exact_def);
  441.         return exact_def.pixel;
  442.     }
  443.     else
  444.         return monocolor;
  445. }
  446.  
  447. /* update_x update_y are used for efficiency in playing: instead of
  448.    repainting the whole screen in case of a move, it only paints the
  449.    adjoining cells.
  450. */
  451. void draw_screen()
  452. {
  453.     int i, j;
  454.  
  455.     if (update_x > -1) {
  456.         for ( i = update_y - 1; i < update_y + 2; i++)
  457.             for (j = update_x - 1; j < update_x + 2; j++) 
  458.                 DrawCell(j, i);
  459.         update_x = update_y = -1;
  460.     }
  461.     else {
  462.         for (i = 0; i < height; i++)
  463.             for (j = 0; j < width; j++)
  464.                 DrawCell(j,i);
  465.         DrawShadow(0, 0, width*SWIDTH + 2*BWIDTH - 1, 
  466.                    height*SHEIGHT + 2*BHEIGHT - 1, 3); 
  467.         DrawShadow(BWIDTH-4, BHEIGHT-4, BWIDTH + width*SWIDTH + 3,
  468.                    BHEIGHT + height*SHEIGHT +3, -3);
  469.     }
  470. }
  471.  
  472.  
  473. void keyboard(c)
  474.     int c;
  475. {
  476.     switch(c){
  477.         case 'q':
  478.             quit();
  479.             break;
  480.         case 'c':
  481.             break;
  482.         default:
  483.             return;
  484.     }
  485.     newscreen();
  486.     clearscreen = 1;
  487. }
  488.  
  489. void DrawCell(x, y)
  490.     int x;
  491.     int y;
  492.  
  493. {
  494.     int val;
  495.  
  496.     if(InArray(x,y)) {
  497.         val = myarr[x][y];
  498.         XCopyArea(display, patpix[val], xwin, gc, 0, 0, SWIDTH, SHEIGHT,
  499.                   x*SWIDTH + BWIDTH ,y*SHEIGHT + BHEIGHT);
  500.     }
  501. }
  502.  
  503. DrawShadow(x1,y1,x2,y2,dir)
  504.     int x1;
  505.     int y1;
  506.     int x2;
  507.     int y2;
  508.     int dir;
  509. {
  510.     int i;
  511.     GC highlightgc,shadowgc;
  512.     unsigned long patbg, patfg;
  513.  
  514.     highlightgc = XCreateGC(display, xwin, 0, 0);
  515.     shadowgc = XCreateGC(display, xwin, 0, 0);
  516.     if(!mono) {
  517.         patbg = getcolor("gray", background); 
  518.         patfg = getcolor("black", foreground);
  519.     }
  520.  
  521.     if(dir < 0) {
  522.         XSetForeground(display, highlightgc, patfg);
  523.         XSetForeground(display, shadowgc, patbg);
  524.         dir = -dir;
  525.     }
  526.     else {
  527.         XSetForeground(display, shadowgc, patfg);
  528.         XSetForeground(display, highlightgc, patbg);
  529.     }
  530.  
  531.     for(i=0; i < dir; i++) {
  532.         XDrawLine(display,xwin,highlightgc,x1,y1,x1,y2);
  533.         XDrawLine(display,xwin,shadowgc,x1,y2,x2,y2);
  534.         XDrawLine(display,xwin,shadowgc,x2,y1,x2,y2);
  535.         XDrawLine(display,xwin,highlightgc,x1,y1,x2,y1);
  536.         x1++; x2--; y1++; y2--;
  537.     }
  538. }
  539.